#include "opencv2\highgui\highgui.hpp"
#include <vector>
#include "HierElement.h"


namespace OpLib{

	struct WeightedRect{
		cv::Rect rect;
		double	weight;
	};

	using namespace cv;

	class WorkingObject : public HierElement{
	private:

		/*!
		*Compares 2 rects, returns true if overlap exceeds overlap_border*size
		* @param rect_1 Rectangle 1
		* @param rect_2 Rectangle 2
		* @param overlap_border defines the border for the overlap - should be a value betweeen 0.0 and 1.0
		* @return True, if overlap exceeds 50%
		*/
		bool checkForOverlap(cv::Rect rect_1, cv::Rect rect_2, double overlap_border){
			Rect intersectionRect = rect_1 & rect_2;

			int intersection = intersectionRect.size().height*intersectionRect.size().width;

			int area1 = rect_1.height*rect_1.width;
			int area2 = rect_2.height*rect_2.width;

			int unioN = area1+area2-intersection;
			double overlap = ((double) intersection) / ((double) unioN);
			if( overlap > overlap_border){
				return true;
			}else{
				return false;
			}
		}

	public: 

		std::vector<WeightedRect> found_hits;

		WorkingObject(){
			//type_name="Base Image";
			std::vector<WeightedRect> found_hits(0);
		}
				
		/*!
		* Deletes hits if sliding windows have an overlap from 20%
		*/
		void	deleteOverlappingPositiveHits(){
			std::vector<WeightedRect> rects=found_hits;
			for (int i=0; i<rects.size(); i++){
				for (int j=i+1; j<rects.size(); j++){
					// both overlapping
					if (checkForOverlap(rects[i].rect, rects[j].rect, 0.2)){
						// higher weight
						if (rects[i].weight >= rects[j].weight){
							// delete element at position j
							rects.erase(rects.begin()+j);
							j--;
						}
						// lower weight
						else{
							// delete element at position i
							rects.erase(rects.begin()+i);
							j--;
						}
					}
				}
			}
		}

		//!	The source image.
		Mat source_image;

		//! The filename
		String filename;

		//!	the coordinates of the detected objects in this image.
		vector<Rect> found_objects;

		vector<HierElement *> getLowscaledImageObjects(){
			return this->getLowerElements();
		}
	};
}